/* 
 * artist definition
 *
 * Choi Jonghwan<saxboy@gmail.com>
 * 2006/04/23
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "artist.h"

ARTIST artist_New(void)
{
	ARTIST a=NULL; 

	if ( (a=(ARTIST)malloc(sizeof(_ARTIST))) != NULL)
	{
		memset(a, 0, sizeof(_ARTIST)); 
	}

	return a; 
}

ARTIST artist_NewWithName(const char *name)
{
	ARTIST a=NULL; 

	if ( (a=artist_New())!=NULL)
	{
		if ( artist_Load(a, name) > 0 )
			return a; 
	}

	artist_Delete(a); 
	return NULL; 
}

int artist_Delete(ARTIST a)
{
	if (a==NULL) return -1; 
	artiststyle_Delete(a->style); 
	free(a); 
	return 1; 
}

int artist_SetInstrument(ARTIST a, INSTRUMENT i)
{
	if (a==NULL) return -1; 
	if (i==NULL) return -1; 
	a->instrument = i; 
	return 1; 
}

int artist_SetArtistStyle(ARTIST a, ARTISTSTYLE style)
{
	if (a==NULL) return -1; 
	if (style==NULL) return -1; 
	a->style = style; 
	return 1; 
}

#if 0
struct __artist_handlers {
	char *name; 
	int (*handler)(ARTIST a, SONG song, VOICE v); 
} g_artist_handlers[] = {
	{"jazz pianist", artist_jazz_pianist}, 
	{"latin bassist", artist_latin_bassist}, 
	{"bebop bassist", artist_bebop_bassist}, 
	{"rock bassist", artist_rock_bassist}, 
	{"jazz saxophonist", artist_jazz_saxophonist}, 
	{"bebop drummer", artist_bebop_drummer}, 
	{"latin drummer", artist_latin_drummer}, 
	{NULL, NULL}
}; 
#endif

int artist_Load(ARTIST a, const char *name)
{
	if (a==NULL) return -1; 
	if (name==NULL) return -1; 

	{
		int i=0; 

#if 0
		for (i=0; g_artist_handlers[i].name !=NULL; i++)
		{
			if (strcmp(name, g_artist_handlers[i].name )==0 )
			{
				a->handler =  g_artist_handlers[i].handler; 
				return 1; 
			}
		}
#endif
		return 1; 

	}

	return -1; 
}

int artist_RenderSongToVoice(ARTIST a, SONG s, VOICE v)
{
	if (a==NULL) return -1; 
	if (s==NULL) return -1; 
	if (v==NULL) return -1; 

	/* FIXME: 
	 * do not use hander,
	 * instead use registered patterns for given artist style 
	 */
	v->instrument = a->instrument; 

	if ( a->b_is_drummer )
	{
		v->b_is_drummer = 1; 
		artiststyle_ApplyDrumStyleForSong(a->style, s, v); 
	}
	else
	{
		/* TODO: we can apply artist creativity here... */
		artiststyle_ApplyStyleForSong(a->style, s, v); 
	}

	return 1; 
}

#if 0
int artist_jazz_pianist(ARTIST a, SONG song, VOICE v)
{
	ARTISTSTYLE style = a->style; 

	{
		int i=0; 
		int j=0; 
		for (i=0; i< song->bar_count; i++)
		{
			BAR b = song->bars[i]; 

			voice_AddEvent(v, VOICE_EVENT_BAR_START, NULL); 
			//for (j=0; j< b->measure_count; j++)
			{
				CHORD c = bar_GetChord(b, j); 
			}
			voice_AddEvent(v, VOICE_EVENT_BAR_END, NULL); 
		}
	}

	return 1; 
}

int artist_bebop_bassist(ARTIST a, SONG song, VOICE v)
{
	ARTISTSTYLE style = a->style; 
	{
		int i=0; 
		int j=0; 
		for (i=0; i< song->bar_count; i++)
		{
			BAR b = song->bars[i]; 

			voice_AddEvent(v, VOICE_EVENT_BAR_START, NULL); 
			for (j=0; j< b->measure_count; j++)
			{
				CHORD c = bar_GetChord(b, j); 

			}
			voice_AddEvent(v, VOICE_EVENT_BAR_END, NULL); 
		}
	}

	return 1; 

}

int artist_latin_bassist(ARTIST a, SONG song, VOICE v)
{
	ARTISTSTYLE style = a->style; 
	{
		int i=0; 
		int j=0; 
		for (i=0; i< song->bar_count; i++)
		{
			BAR b = song->bars[i]; 

			voice_AddEvent(v, VOICE_EVENT_BAR_START, NULL); 

			if ( bar_GetChordCount(b) >0 )
			{
				CHORD c = bar_GetChord(b, 0); 
				PATTERN p = pattern_latin_bass_1; 

				if ( artiststyle_ApplyPattern( style, p, c, v) < 0 )
					return -1; 
			}
			else 
			{
				for (j=0; j< b->measure_count; j++)
				{
					CHORD c = bar_GetChord(b, j); 
					PATTERN p1 = pattern_latin_bass_two_chord1; 
					PATTERN p2 = pattern_latin_bass_two_chord2; 
	
					if ( artiststyle_ApplyPattern( style, p1, c, v) < 0 )
						return -1; 
					if ( artiststyle_ApplyPattern( style, p2, c, v) < 0 )
						return -1; 

				}

			}

			voice_AddEvent(v, VOICE_EVENT_BAR_END, NULL); 
		}
	}

	return 1; 
}

int artist_rock_bassist(ARTIST a, SONG song, VOICE v)
{
	ARTISTSTYLE style = a->style; 
	{
		int i=0; 
		int j=0; 
		for (i=0; i< song->bar_count; i++)
		{
			BAR b = song->bars[i]; 

			voice_AddEvent(v, VOICE_EVENT_BAR_START, NULL); 
			for (j=0; j< b->measure_count; j++)
			{
				CHORD c = bar_GetChord(b, j); 
				PATTERN p = pattern_rock_bass_1; 

				if ( artiststyle_ApplyPattern( style, p, c, v) < 0 )
					return -1; 
			}
			voice_AddEvent(v, VOICE_EVENT_BAR_END, NULL); 
		}
	}

	return 1; 
}
int artist_jazz_saxophonist(ARTIST a, SONG song, VOICE v)
{
	ARTISTSTYLE style = a->style; 
	{
		int i=0; 
		int j=0; 
		for (i=0; i< song->bar_count; i++)
		{
			BAR b = song->bars[i]; 

			voice_AddEvent(v, VOICE_EVENT_BAR_START, NULL); 
			//for (j=0; j< b->measure_count; j++)
			{
				//CHORD c = bar_GetChord(b, j); 
				CHORD c = bar_GetChord(b, 0); 
				PATTERN p = pattern_jazz_sax; 

				if ( artiststyle_ApplyPattern( style, p, c, v) < 0 )
					return -1; 

			}
			voice_AddEvent(v, VOICE_EVENT_BAR_END, NULL); 
		}
	}

	return 1; 
}
#endif

int artist_bebop_drummer(ARTIST a, SONG song, VOICE v)
{
	ARTISTSTYLE style = a->style; 
	v->b_is_drummer = 1; 

	sprintf(v->drum_pattern, "d4d3dd4d3d 51 51 51 51 51 51"); 

	return 1; 
}

int artist_latin_drummer(ARTIST a, SONG song, VOICE v)
{
	ARTISTSTYLE style = a->style; 
	v->b_is_drummer = 1; 

	sprintf(v->drum_pattern, "d2d2zdzdzdz2d2d2 61 61 61 61 61 61 61 61 61 61"); 
	return 1; 
}


/* 6/8 slow shuffle... */
int artist_slow_shuffle_drummer(ARTIST a, SONG song, VOICE v)
{
	ARTISTSTYLE style = a->style; 
	v->b_is_drummer = 1; 

	sprintf(v->drum_pattern, "d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38 38"); 
	return 1; 
}






